home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
util
/
cli
/
MCommands_1_2.lha
/
Src
/
rxcontrol.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-02
|
10KB
|
408 lines
/****************************************************************************/
/* RXControl.c */
/* Control features of ARexx */
/* Copyright © 1994 MIchael Letowski */
/****************************************************************************/
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/rdargs.h>
#include <dos/dos.h>
#include <rexx/rxslib.h>
#include <intuition/intuition.h>
#include <workbench/startup.h>
#include <support/types.h>
#include <support/exec.h>
#include <support/dos.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/rexxsyslib.h>
#include <proto/intuition.h>
#include <proto/icon.h>
#include "rxcontrol.rev.h"
#define DOS_NAME "dos.library"
#define REXX_NAME "rexxsyslib.library"
#define INTUI_NAME "intuition.library"
#define ICON_NAME "icon.library"
#define DOS_VERN 37L
#define REXX_VERN 36L
#define INTUI_VERN 37L
#define ICON_VERN 37L
#define RXPORT_NAME "REXX"
#define RXCONTROL_NAME "RXControl"
#define TEMPLATE "CANCEL=RXC/S,HALT=HI/S,SUSPEND/S,RESUME/S,"\
"TRACESTART=TS/S,TRACEEND=TE/S,"\
"CONOPEN=TCO/S,CONCLOSE=TCC/S,"\
"QUIET/S"
#define OPT_RXC 0
#define OPT_HI 1
#define OPT_SUSPEND 2
#define OPT_RESUME 3
#define OPT_TS 4
#define OPT_TE 5
#define OPT_TCO 6
#define OPT_TCC 7
#define OPT_QUIET 8
#define OPT_COUNT 9
/* Messages */
#define UNABLE_OPEN "Unable to open '%s'\n"
#define NOT_ACTIVE "ARexx server not active\n"
#define IS_SUSPENDED "Execution is suspended\n"
#define WILL_CLOSE "RexxMaster will close\n"
/* Other texts */
#define OK "OK"
#define ON "ON"
#define OFF "OFF"
#define OPEN "open"
#define CLOSED "closed"
#define REQUEST_MSG " Request"
#define INFO_MSG " Information"
#define SPC_TAB " "
STATIC CONST TEXT VersionString[]=
VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
struct Switch
{
STRPTR sw_Name;
ULONG sw_Index;
};
ULONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
ULONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
ULONG RXControl(VOID)
{
struct ExecBase *SysBase=*((struct ExecBase **)4);
struct DosLibrary *DOSBase;
ULONG RC=RETURN_FAIL;
unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
{
SetResult2(ERROR_INVALID_RESIDENT_LIBRARY);
goto InvalidDOS;
}
RC=FromWB ? WBMode(SysBase,DOSBase) : CLIMode(SysBase,DOSBase);
CloseLibrary((struct Library *)DOSBase);
InvalidDOS:
return(RC);
}
/* CLI mode work */
ULONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct RxsLib *RexxSysBase;
struct RDArgs *Args;
struct MsgPort *Port;
struct RexxMsg *RXMsg;
LONG Options[OPT_COUNT];
ULONG RC=RETURN_FAIL;
BOOL ErrOccured=FALSE;
unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
{
CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,NULL);
goto InvalidREXX;
}
/* Read options */
clear(&Options); /* Clear options buffer */
unless(Args=ReadArgs(TEMPLATE,Options,NULL))
{
PrintFault(IoErr(),NULL); /* Inform user */
goto NoArgs;
}
/* Check for REXX port */
Forbid();
unless(Port=FindPort(RXPORT_NAME))
{
Permit();
PutStr(NOT_ACTIVE);
goto NotActive;
}
/* RXC */
if(Options[OPT_RXC])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXCLOSE | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
{
CauseIoErr(ERROR_NO_FREE_STORE,NULL);
ErrOccured=TRUE;
}
}
/* HI */
if(Options[OPT_HI])
{
bset(RexxSysBase->rl_Flags,RLFB_HALT);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
/* Suspend/Resume */
if(Options[OPT_SUSPEND])
{
bset(RexxSysBase->rl_Flags,RLFB_SUSP);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
if(Options[OPT_RESUME])
{
bclr(RexxSysBase->rl_Flags,RLFB_SUSP);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
/* TE/TS */
if(Options[OPT_TE])
bclr(RexxSysBase->rl_Flags,RLFB_TRACE);
if(Options[OPT_TS])
bset(RexxSysBase->rl_Flags,RLFB_TRACE);
/* TCO/TCC */
if(Options[OPT_TCO])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXTCOPN | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
{
CauseIoErr(ERROR_NO_FREE_STORE,NULL);
ErrOccured=TRUE;
}
}
if(Options[OPT_TCC])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXTCCLS | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
{
CauseIoErr(ERROR_NO_FREE_STORE,NULL);
ErrOccured=TRUE;
}
}
Permit();
unless(Options[OPT_QUIET])
{
Printf("ARexx state:\n"
"\tTracing is %s\n"
"\tTrace console is %s\n%s%s",
btst(RexxSysBase->rl_Flags,RLFB_TRACE) ? ON : OFF,
RexxSysBase->rl_TraceFH ? OPEN : CLOSED,
btst(RexxSysBase->rl_Flags,RLFB_SUSP) ?
"\t" IS_SUSPENDED : NULL,
btst(RexxSysBase->rl_Flags,RLFB_CLOSE) ?
"\t" WILL_CLOSE : NULL);
}
RC=(ErrOccured ? RETURN_ERROR : RETURN_OK);
NotActive:
FreeArgs(Args);
NoArgs:
CloseLibrary((struct Library *)RexxSysBase);
InvalidREXX:
return(RC);
}
/* Workbench mode work */
ULONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct IntuitionBase *IntuitionBase;
struct RxsLib *RexxSysBase;
struct Library *IconBase;
STATIC CONST struct EasyStruct NoLibReq=
{
sizeof(struct EasyStruct),0,
RXCONTROL_NAME REQUEST_MSG,
UNABLE_OPEN,
OK
};
STATIC CONST struct EasyStruct NotActiveReq=
{
sizeof(struct EasyStruct),0,
RXCONTROL_NAME REQUEST_MSG,
NOT_ACTIVE,
OK
};
STATIC CONST struct EasyStruct InfoReq=
{
sizeof(struct EasyStruct),0,
RXCONTROL_NAME INFO_MSG,
"ARexx state:\n"
SPC_TAB "Tracing is %s\n"
SPC_TAB "Trace console is %s\n%s%s",
OK
};
STATIC CONST struct Switch Switches[]=
{
{"CANCEL",OPT_RXC}, {"RXC",OPT_RXC},
{"HALT",OPT_HI}, {"HI",OPT_HI},
{"SUSPEND",OPT_SUSPEND},
{"RESUME",OPT_RESUME},
{"TRACESTART",OPT_TS}, {"TS",OPT_TS},
{"TRACEEND",OPT_TE}, {"TE",OPT_TE},
{"CONOPEN",OPT_TCO}, {"TCO",OPT_TCO},
{"CONCLOSE",OPT_TCC}, {"TCC",OPT_TCC},
{"QUIET",OPT_QUIET}
};
struct WBArg *Args;
struct MsgPort *Port;
struct RexxMsg *RXMsg;
struct WBStartup *WBMsg;
struct DiskObject *Object;
STRPTR *ToolArray;
BPTR OldDir;
LONG Options[OPT_COUNT];
ULONG I,J,RC=RETURN_FAIL;
BOOL ErrOccured=FALSE;
WaitPort(&ThisProcessS->pr_MsgPort);
WBMsg=(struct WBStartup *)GetMsg(&ThisProcessS->pr_MsgPort);
unless(IntuitionBase=
(struct IntuitionBase *)OpenLibrary(INTUI_NAME,INTUI_VERN))
{
SetResult2(ERROR_INVALID_RESIDENT_LIBRARY);
goto InvalidIntuition;
}
unless(IconBase=OpenLibrary(ICON_NAME,ICON_VERN))
{
EasyRequest(NULL,&NoLibReq,NULL,ICON_NAME);
goto InvalidIcon;
}
unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
{
EasyRequest(NULL,&NoLibReq,NULL,REXX_NAME);
goto InvalidREXX;
}
clear(&Options); /* Clear options buffer */
for(I=0, Args=WBMsg->sm_ArgList; I<WBMsg->sm_NumArgs; I++, Args++)
{
if(Args->wa_Lock && *Args->wa_Name)
{
OldDir=CurrentDir(Args->wa_Lock);
if(*Args->wa_Name && (Object=GetDiskObject(Args->wa_Name)))
{
ToolArray=(STRPTR *)Object->do_ToolTypes;
for(J=0; J<sizeof(Switches)/sizeof(struct Switch); J++)
if(FindToolType(ToolArray,Switches[J].sw_Name))
Options[Switches[J].sw_Index]=TRUE;
FreeDiskObject(Object);
}
CurrentDir(OldDir); /* CD back */
}
}
/* Check for REXX port */
Forbid();
unless(Port=FindPort(RXPORT_NAME))
{
Permit();
EasyRequest(NULL,&NotActiveReq,NULL);
goto NotActive;
}
/* RXC */
if(Options[OPT_RXC])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXCLOSE | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
ErrOccured=TRUE;
}
/* HI */
if(Options[OPT_HI])
{
bset(RexxSysBase->rl_Flags,RLFB_HALT);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
/* Suspend/Resume */
if(Options[OPT_SUSPEND])
{
bset(RexxSysBase->rl_Flags,RLFB_SUSP);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
if(Options[OPT_RESUME])
{
bclr(RexxSysBase->rl_Flags,RLFB_SUSP);
Signal(Port->mp_SigTask,flag(Port->mp_SigBit));
}
/* TE/TS */
if(Options[OPT_TE])
bclr(RexxSysBase->rl_Flags,RLFB_TRACE);
if(Options[OPT_TS])
bset(RexxSysBase->rl_Flags,RLFB_TRACE);
/* TCO/TCC */
if(Options[OPT_TCO])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXTCOPN | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
ErrOccured=TRUE;
}
if(Options[OPT_TCC])
{
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL))
{
RXMsg->rm_Action=RXTCCLS | RXFF_NONRET;
PutMsg(Port,(struct Message *)RXMsg);
}
else
ErrOccured=TRUE;
}
Permit();
unless(Options[OPT_QUIET])
{
EasyRequest(NULL,&InfoReq,NULL,
btst(RexxSysBase->rl_Flags,RLFB_TRACE) ? ON : OFF,
RexxSysBase->rl_TraceFH ? OPEN : CLOSED,
btst(RexxSysBase->rl_Flags,RLFB_SUSP) ?
SPC_TAB IS_SUSPENDED : NULL,
btst(RexxSysBase->rl_Flags,RLFB_CLOSE) ?
SPC_TAB WILL_CLOSE : NULL);
}
RC=(ErrOccured ? RETURN_ERROR : RETURN_OK);
NotActive:
NoArgs:
CloseLibrary((struct Library *)RexxSysBase);
InvalidREXX:
CloseLibrary(IconBase);
InvalidIcon:
CloseLibrary((struct Library *)IntuitionBase);
InvalidIntuition:
ReplyMsg((struct Message *)WBMsg);
return(RC);
}